package org.labuladong.滑动窗口;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * @author Fql18
 * @Auther: qingle
 * @Date: 2024/10/24-22:56
 * @Description:
 *
这段代码使用两个指针left和right来表示子串的开始和结束位置。
同时使用一个HashSet来存储当前子串中的字符。
当right指针遍历到一个字符，如果这个字符已经在HashSet中，说明出现了重复，此时需要移动left指针，直到重复的字符被移出HashSet。
每次移动right指针时，都会尝试将当前字符加入HashSet，并更新最长子串的长度。
最终返回maxLen即为所求的最长子串长度。
 * @version: 1.0
 */
public class LCR_016_无重复字符的最长子串_labuladong {

	static class Solution {
		public int lengthOfLongestSubstring(String s) {
			Map<Character, Integer> window = new HashMap<>();
			int left = 0, right = 0;
			int res = 0; // 记录结果

			while (right < s.length()) {
				char c = s.charAt(right);
				right++;

				// 进行窗口内数据的一系列更新
				window.put(c, window.getOrDefault(c, 0) + 1);

				// 判断左侧窗口是否要收缩
				while (window.get(c) > 1) {
					char d = s.charAt(left);
					left++;
					// 进行窗口内数据的一系列更新
					window.put(d, window.get(d) - 1);
				}

				// 在这里更新答案
				res = Math.max(res, right - left);
			}

			return res;
		}
	}

	public static void main(String[] args) {
		Solution solution = new Solution();

		// 测试用例1：包含重复字符
		String test1 = "abcabcbb";
		System.out.println("Length of longest substring without repeating characters: " + solution.lengthOfLongestSubstring(test1)); // 应输出 3

		// 测试用例2：没有重复字符
		String test2 = "bbbbb";
		System.out.println("Length of longest substring without repeating characters: " + solution.lengthOfLongestSubstring(test2)); // 应输出 1

		// 测试用例3：空字符串
		String test3 = "";
		System.out.println("Length of longest substring without repeating characters: " + solution.lengthOfLongestSubstring(test3)); // 应输出 0

		// 测试用例4：所有字符都相同
		String test4 = "aaaaaa";
		System.out.println("Length of longest substring without repeating characters: " + solution.lengthOfLongestSubstring(test4)); // 应输出 1

		// 测试用例5：没有重复字符的字符串
		String test5 = "abc";
		System.out.println("Length of longest substring without repeating characters: " + solution.lengthOfLongestSubstring(test5)); // 应输出 3

		// 测试用例6：包含特殊字符
		String test6 = "abcabcde";
		System.out.println("Length of longest substring without repeating characters: " + solution.lengthOfLongestSubstring(test6)); // 应输出 5

		// 测试用例7：包含数字和字符
		String test7 = "aababcabc";
		System.out.println("Length of longest substring without repeating characters: " + solution.lengthOfLongestSubstring(test7)); // 应输出 3

		// 测试用例8：大字符串
		String test8 = "abbbbcccaaadeeeaa";
		System.out.println("Length of longest substring without repeating characters: " + solution.lengthOfLongestSubstring(test8)); // 应输出 3
	}
}
